package edu.pku.sei.transformation.editor.controller.commands.node;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.gef.commands.Command;

import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.structure.MetaDiagram;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.structure.StructureFactory;
import edu.pku.sei.transformation.editor.model.AtomicTransformation;
import edu.pku.sei.transformation.editor.model.Rule;
import edu.pku.sei.transformation.editor.model.Transformation;

public class RuleCreateCommand extends Command {
	private AtomicTransformation transformation;
	private Rule rule;
	private List<MetaDiagram> extendbyDiagrams = new ArrayList<MetaDiagram>();
	private List<MetaNode> referenceNodes = new ArrayList<MetaNode>();

	public RuleCreateCommand(AtomicTransformation transformation, Rule rule) {
		this.transformation = transformation;
		this.rule = rule;
	}

	@Override
	public boolean canExecute() {
		if (this.transformation != null && this.rule != null) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public void execute() {
		super.execute();
		// while(!transformation.registerName(rule.getName(), rule)) {
		// rule.setName(rule.getName() + "_r");
		// }
		
		//add rules to those transformation that extends this transformation
		try {
			StructureFactory factory = (StructureFactory) ModelRegistry.getRegistry().getStructureFactory(transformation.getModel());
			for (Transformation t : transformation.getAllExtendby()) {
				if (t instanceof AtomicTransformation && t.getDiagram() != null) {
					MetaNode node = factory.createMetaNode();
					node.setModelElement(rule);
					node.setLocationX(10);
					node.setLocationX(10);
					node.setWidth(100);
					node.setHeight(50);
					extendbyDiagrams.add(t.getDiagram());
					referenceNodes.add(node);
					t.getDiagram().getNodes().add(node);
				}
			}
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FactoryNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

		transformation.getRules().add(rule);
		rule.setOwner(transformation);
		transformation.getMetaPackage().getOtherElements().add(rule);
		rule.setContainer(transformation.getMetaPackage());
	}

	@Override
	public void undo() {
		super.undo();
		for (int i = 0; i < extendbyDiagrams.size(); i++) {
			extendbyDiagrams.get(i).getNodes().remove(referenceNodes.get(i));
		}
		
		
		
		
		transformation.getRules().remove(rule);
		rule.setOwner(null);
		transformation.getMetaPackage().getOtherElements().remove(rule);
		rule.setContainer(null);
	}
}
